package com.yl.chainStore.services.impl

import com.alibaba.fastjson.JSONObject
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
import com.baomidou.mybatisplus.core.toolkit.Wrappers
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.yl.chainStore.common.Constants
import com.yl.chainStore.common.Constants.StrShow.Companion.CUSTOMER_MOBILE_SELF
import com.yl.chainStore.common.Constants.StrShow.Companion.CUSTOMER_MOBILE_TO_CUSTOMER_TYPE_SELF_ID
import com.yl.chainStore.common.enums.Status
import com.yl.chainStore.common.enums.TypeEnum
import com.yl.chainStore.entity.customer.*
import com.yl.common.control.ResponseBody
import com.yl.common.control.returnSuccess
import com.yl.chainStore.entity.pay.*
import com.yl.chainStore.entity.sick.*
import com.yl.chainStore.entity.warehouse.TechnologyProcessing
import com.yl.chainStore.mapper.customer.*
import com.yl.chainStore.mapper.pay.*
import com.yl.chainStore.mapper.sick.*
import com.yl.chainStore.mapper.system.CompanyDictionaryDetailMapper
import com.yl.chainStore.mapper.warehouse.TechnologyProcessingMapper
import com.yl.chainStore.pojo.vo.customer.CustomerInfoAssociatedUpdateVo
import com.yl.chainStore.pojo.vo.customer.CustomerLeftJoinInfo
import com.yl.chainStore.pojo.vo.customer.CustomerSelectVo
import com.yl.chainStore.pojo.vo.pay.*
import com.yl.chainStore.pojo.vo.sick.*
import com.yl.chainStore.pojo.vo.warehouse.TechnologyProcessingMapperVo
import com.yl.chainStore.services.*
import com.yl.chainStore.services.pay.ISysCompanyPayItemService
import com.yl.chainStore.services.sick.ICustomerSubscribeLogService
import com.yl.chainStore.services.sick.ISickMedicalRecordsService
import com.yl.chainStore.util.*
import com.yl.common.ErrorCode
import com.yl.common.control.returnError
import com.yl.common.getContext
import com.yl.message.common.MessageType
import com.yl.message.service.ISendMessageService
import com.yl.message.websocket.WebSocketMessageType
import com.yl.message.websocket.WebSocketMessageVo
import com.yl.users.entity.CompanyUser
import com.yl.users.services.ICompanyDeptService
import com.yl.users.services.ICompanyUserService
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.springframework.transaction.interceptor.TransactionAspectSupport
import java.io.File
import java.util.*

@Service("iCustomerInfoService")
class CustomerInfoServiceImpl(

    private val customerInfoMapper: CustomerInfoMapper,
    private val sickCustomerImageMapper: SickCustomerImageMapper,
    private val sickMedicalRecordsMapper: SickMedicalRecordsMapper,
    private val sickMedicalRecordsDetailMapper: SickMedicalRecordsDetailMapper,
    private val sickMedicalHistoryMapper: SickMedicalHistoryMapper,
    private val sickCustomerAccessLogMapper: SickCustomerAccessLogMapper,
    private val customerSubscribeLogMapper: CustomerSubscribeLogMapper,

    private val payCustomerAccountMapper: PayCustomerAccountMapper,
    private val payCustomerBalanceInLogMapper: PayCustomerBalanceInLogMapper,
    private val payCustomerMoneyFlowMapper: PayCustomerMoneyFlowMapper,
    private val payCustomerIntegralFlowMapper: PayCustomerIntegralFlowMapper,
    private val payCustomerBalanceToCustomerLogMapper: PayCustomerBalanceToCustomerLogMapper,
    private val payCustomerBalanceToMoneyLogMapper: PayCustomerBalanceToMoneyLogMapper,

    private val payCustomerCouponsMapper: PayCustomerCouponsMapper,
    private val payCustomerOrderMapper: PayCustomerOrderMapper,
    private val payCustomerOrderDetailMapper: PayCustomerOrderDetailMapper,
    private val payCompanyCouponsModelMapper: PayCompanyCouponsModelMapper,
    private val payCustomerOrderItemOperatorLogMapper: PayCustomerOrderItemOperatorLogMapper,
    private val payOrderCustomerPayLogMapper: PayOrderCustomerPayLogMapper,
    private val payOrderCustomerPayLogDetailMapper: PayOrderCustomerPayLogDetailMapper,
    private val payCustomerGiftsOfGoldMapper: PayCustomerGiftsOfGoldMapper,


    private val technologyProcessingMapper: TechnologyProcessingMapper,

    private val customerInfoSourceDistMapper: CustomerInfoSourceDistMapper,
    private val customerInfoSecondSourceMapper: CustomerInfoSecondSourceMapper,
    private val customerInfoPhoneMapper: CustomerInfoPhoneMapper,
    private val companyDictionaryDetailMapper: CompanyDictionaryDetailMapper,
    private val customerInfoAssociatedMapper: CustomerInfoAssociatedMapper,
    private val sickCustomerAccessLogPlanMapper: SickCustomerAccessLogPlanMapper,
    private val sickCustomerAccessLogPlanDetailMapper: SickCustomerAccessLogPlanDetailMapper,

    private val customerDeptConfigMapper: CustomerDeptConfigMapper,


    ) : ICustomerInfoService {

    @Autowired
    lateinit var iSickMedicalRecordsService: ISickMedicalRecordsService

    @Autowired
    lateinit var iSysCompanyPayItemService: ISysCompanyPayItemService

    @Autowired
    lateinit var iTechnologyProcessingService: ITechnologyProcessingService

    @Autowired
    lateinit var iCompanyUserOperationLogService: ICompanyUserOperationLogService

    @Autowired
    private lateinit var companyDeptService: ICompanyDeptService

    @Autowired
    private lateinit var iWebCompanyService: IWebCompanyService

    @Autowired
    private lateinit var iSendMessageService: ISendMessageService

    @Autowired
    private lateinit var iSysNumGeneratorService: ISysNumGeneratorService

    @Autowired
    private lateinit var iCustomerSubscribeLogService: ICustomerSubscribeLogService

    @Autowired
    private lateinit var iCompanyUserService: ICompanyUserService



    companion object {
        private val log = LoggerFactory.getLogger(ICustomerInfoService::class.java)
    }

    override fun getById(id: Long): CustomerInfo? {
        log.info("客户操作：==>获取用户基本信息：id:{}", id)
        return customerInfoMapper.selectById(id)
    }

    override fun getJoinInfoByCustomerId(id: Long, joinInfo: CustomerLeftJoinInfo): CustomerInfo? {
        val info = getById(id) ?: return null
        info.showRules = getShowRuleByOrderDetail(id, getContext().subCompanyId)
        info.hasArrearsOrder = customerHaveArrearsOrder(id)
        joinInfo.customerInfo = info
        joinInfo.customerName = info.name
        joinInfo.from = info.scoreShow
        getMobileStr(info)
        getMobileFirstStr(info)
        joinInfo.customerPhone = info.mobileNumStr
        joinInfo.customerSex = info.gender
        joinInfo.customerHistorySickNum = info.historySickNum
        joinInfo.age = info.age
        joinInfo.hasArrearsOrder = info.hasArrearsOrder
        joinInfo.showRules = info.showRules
        return info
    }

    override fun update(customerInfo: CustomerInfo): ResponseBody {
        log.info("客户操作：==>修改用户信息：customerInfo:{}", customerInfo)
        val oldInfo = customerInfoMapper.selectById(customerInfo.id) ?: return returnError(
            ErrorCode.DATA_IS_NOT_FIND,
            "未找到用户信息，请刷新重试"
        )
        if (customerInfo.birthDate != null) {
            val toDay = Date()
            setDayFirstTime(toDay)
            if (toDay.before(customerInfo.birthDate)) {
                return returnError(
                    ErrorCode.DATA_SAVE_FAILED,
                    "生日日期错误"
                )
            }
        }
        oldInfo.gender = customerInfo.gender

        customerInfoMapper.updateById(customerInfo)
        return returnSuccess()
    }

    override fun updateSource(customerInfo: CustomerInfo): ResponseBody {
        customerInfoMapper.update(
            null, Wrappers.update<CustomerInfo>()
                .eq("id", customerInfo.id)
                .set("first_source", customerInfo.firstSource)
                .set("second_source_id", customerInfo.secondSourceId)
                .set("source_company_user_id", customerInfo.sourceCompanyUserId)
                .set("source_customer_id", customerInfo.sourceCustomerId)
                .set("source_dist_id", customerInfo.sourceDistId)
        )
        return returnSuccess()
    }

    override fun setMobile(customerId: Long, phoneList: List<CustomerInfoPhone>): ResponseBody {
        customerInfoPhoneMapper.delete(
            Wrappers.query<CustomerInfoPhone?>()
                .eq("customer_id", customerId)
                .eq("phone_type", TypeEnum.CUSTOMER_PHONE_TYPE_MOBILE.code)
        )
        for (phone in phoneList) {
            if (phone.phoneToCustomerType == CUSTOMER_MOBILE_TO_CUSTOMER_TYPE_SELF_ID) {
//                if (customerInfoPhoneMapper.haveSameMobileBySelf(getContext().companyId, phone.phone) != 0) {
//                    return returnError(ErrorCode.DATA_SAVE_FAILED, "本人手机号码重复")
//                }
            }
            phone.customerId = customerId
            phone.phoneType = TypeEnum.CUSTOMER_PHONE_TYPE_MOBILE
            customerInfoPhoneMapper.insert(phone)
        }
        return returnSuccess()
    }

    override fun getMobile(customerInfo: CustomerInfo): ResponseBody {
        customerInfo.mobileNum = customerInfoPhoneMapper.selectList(
            Wrappers.query<CustomerInfoPhone?>()
                .eq("customer_id", customerInfo.id)
                .eq("phone_type", TypeEnum.CUSTOMER_PHONE_TYPE_MOBILE.code)
                .orderByAsc("order_num")
        )
        return returnSuccess()
    }


    override fun getMobileStr(customerInfo: CustomerInfo): ResponseBody {
        if (customerInfo.mobileNum == null) {
            getMobile(customerInfo)
        }
        var mobileStr = ""
        if (customerInfo.mobileNum != null) {
            for (mobile in customerInfo.mobileNum!!) {
                val phoneType = if (mobile.phoneToCustomerType == CUSTOMER_MOBILE_TO_CUSTOMER_TYPE_SELF_ID) {
                    CUSTOMER_MOBILE_SELF
                } else {
                    companyDictionaryDetailMapper.selectById(mobile.phoneToCustomerType)?.itemName ?: ""
                }
                mobileStr = mobileStr + phoneType + ":" + mobile.phone + " "
            }
            customerInfo.mobileNumStr = mobileStr
        }
        return returnSuccess()
    }

    override fun getMobileFirstStr(customerInfo: CustomerInfo): ResponseBody {
        if (customerInfo.mobileNum == null) {
            getMobile(customerInfo)
        }
        if (customerInfo.mobileNum != null) {
            for (mobile in customerInfo.mobileNum!!) {
                if (mobile.phoneToCustomerType == 1L) {
                    customerInfo.mobileFirstNum = mobile.phone
                    customerInfo.mobileFirstNumStr = CUSTOMER_MOBILE_SELF + ":" + mobile.phone
                    return returnSuccess()
                }
            }
            if (customerInfo.mobileNum!!.isNotEmpty()) {
                val mobile = customerInfo.mobileNum!![0]
                val phoneType = companyDictionaryDetailMapper.selectById(mobile.phoneToCustomerType)?.itemName ?: ""
                customerInfo.mobileFirstNum = mobile.phone
                customerInfo.mobileFirstNumStr = phoneType + ":" + mobile.phone
            }
        }
        return returnSuccess()
    }

    override fun setPhone(customerId: Long, phoneList: List<CustomerInfoPhone>): ResponseBody {
        customerInfoPhoneMapper.delete(
            Wrappers.query<CustomerInfoPhone?>()
                .eq("customer_id", customerId)
                .eq("phone_type", TypeEnum.CUSTOMER_PHONE_TYPE_PHONE.code)
        )
        for (phone in phoneList) {
            phone.customerId = customerId
            phone.phoneType = TypeEnum.CUSTOMER_PHONE_TYPE_PHONE
            customerInfoPhoneMapper.insert(phone)
        }
        return returnSuccess()
    }

    override fun getPhone(customerInfo: CustomerInfo): ResponseBody {
        customerInfo.phone = customerInfoPhoneMapper.selectList(
            Wrappers.query<CustomerInfoPhone?>()
                .eq("customer_id", customerInfo.id)
                .eq("phone_type", TypeEnum.CUSTOMER_PHONE_TYPE_PHONE.code)
                .orderByAsc("order_num")
        )
        return returnSuccess()
    }

    override fun getPhoneStr(customerInfo: CustomerInfo): ResponseBody {
        if (customerInfo.phone == null) {
            getPhone(customerInfo)
        }
        var phoneStr = ""
        if (customerInfo.phone != null) {
            for (mobile in customerInfo.phone!!) {
                val phoneType = companyDictionaryDetailMapper.selectById(mobile.phoneToCustomerType)?.itemName ?: ""
                phoneStr = phoneStr + phoneType + ":" + mobile.phone + " "
            }
            customerInfo.phoneNumStr = phoneStr
        }
        return returnSuccess()
    }

    override fun getMobileAndPhone(customerInfo: CustomerInfo): ResponseBody {
        getMobile(customerInfo)
        getPhone(customerInfo)
        return returnSuccess()
    }

    override fun getRecommendedCustomerCount(customerId: Long): Int {
        return customerInfoMapper.selectCount(
            Wrappers.query<CustomerInfo?>()
                .eq("company_id", getContext().companyId)
                .eq("source_customer_id", customerId)
        )
    }

    override fun getRecommendedCustomerList(customerId: Long): List<CustomerInfo> {
        return iWebCompanyService.getCustomerList(
            CustomerSelectVo(
                companyId = getContext().companyId,
                sourceCustomerId = customerId
            )
        )
    }

    override fun addAssociatedCustomer(associate: CustomerInfoAssociated): ResponseBody {
        if (associate.customerId == associate.associatedCustomerId) {
            returnError(ErrorCode.DATA_SAVE_FAILED, "不能与自己关联")
        }
        if (customerInfoAssociatedMapper.selectCount(
                Wrappers.query<CustomerInfoAssociated?>()
                    .eq("customer_id", associate.customerId)
                    .eq("associated_customer_id", associate.associatedCustomerId)
            ) != 0
            || customerInfoAssociatedMapper.selectCount(
                Wrappers.query<CustomerInfoAssociated?>()
                    .eq("customer_id", associate.associatedCustomerId)
                    .eq("associated_customer_id", associate.customerId)
            ) != 0
        ) {
            returnError(ErrorCode.DATA_SAVE_FAILED, "患者之间已存在关联")
        }
        customerInfoAssociatedMapper.insert(associate)
        return returnSuccess()
    }

    override fun delAssociatedCustomer(associateId: Long): ResponseBody {
        customerInfoAssociatedMapper.deleteById(associateId)
        return returnSuccess()
    }

    override fun updateCustomerAssociated(associate: CustomerInfoAssociatedUpdateVo): ResponseBody {
        val oldAssociate = customerInfoAssociatedMapper.selectById(associate.id) ?: return returnError(
            ErrorCode.DATA_IS_NOT_FIND,
            "未找到关联信息"
        )
        oldAssociate.associatedName = associate.associatedName
        oldAssociate.associatedBackName = associate.associatedName
        customerInfoAssociatedMapper.updateById(oldAssociate)
        return returnSuccess()
    }

    override fun getAssociatedList(customerId: Long): List<CustomerInfoAssociated> {
        return customerInfoAssociatedMapper.selectList(
            Wrappers.query<CustomerInfoAssociated?>()
                .eq("customer_id", customerId)
                .or()
                .eq("associated_customer_id", customerId)
        )
    }

    override fun registered(vo: CustomerRegisteredVo): ResponseBody {
        log.info("客户操作：==>挂号：vo:{}", vo)
        //有选择就诊记录，修改就诊记录状态，
        if (vo.recordId == null || vo.recordId == 0L) {
            val onGoingRecord = getOnGoingRecord(vo.customerId)
            if (onGoingRecord.isNotEmpty()) {
                vo.recordId = onGoingRecord[0].id
            } else {
                //没有就诊记录，创建一个就诊记录，
                val record = SickMedicalRecords(
                    customerId = vo.customerId,
                    doctorId = vo.masterUserId,
                    status = Status.ONGOING,
                    actionChief = vo.actionChief ?: "暂无"
                )
                val createMedicalRecords = createMedicalRecords(record)
                if (createMedicalRecords.bodyIsError()) {
                    return createMedicalRecords
                }
                vo.recordId = record.id
            }
        }


        //今日是否有预约记录
        var toDayCustomerSubscribeLog = getCustomerToDayLogNotHaveRecord(vo.customerId, getContext().subCompanyId)
        val subscribeTime = Date()
        setTimeTo15Min(subscribeTime)
        if(toDayCustomerSubscribeLog == null){
            val subscribeLog = CustomerSubscribeLog(
                id = 0,
                customerId = vo.customerId,
                clinicType = vo.registeredType,
                subscribeTime = subscribeTime,
                timeLength = 30,
                consultantId = vo.secondaryUserId,
                doctorId = vo.masterUserId,
                remark = vo.remark,
                status = Status.COMPLETE
            )
            addSubscribeLog(subscribeLog)
            toDayCustomerSubscribeLog = subscribeLog
        }
        val detail = SickMedicalRecordsDetail(
            secondaryUserId = vo.secondaryUserId,
            masterUserId = vo.masterUserId,
            recordId = vo.recordId!!,
            detailType = vo.registeredType,
            medicalSourcesType = vo.medicalSourcesType,
            medicalSources = vo.medicalSources,
            status = Status.WAIT_AUDIT,
            customerId = vo.customerId,
            remark = vo.remark,
            subscribeLogId = toDayCustomerSubscribeLog.id
        )
        iSickMedicalRecordsService.saveDetail(detail)
        refreshLastRecordsDetailId(vo.customerId)
        return returnSuccess()
    }

    override fun getTodayWaitingRecordDetail(customerId: Long): SickMedicalRecordsDetail? {
        val list = sickMedicalRecordsDetailMapper.getList(
            SickMedicalRecordsDetailSelectVo(
                deptId = getContext().subCompanyId,
                customerId = customerId,
                day = Date(),
                status = Status.WAITING
            )
        )
        if (list.isNotEmpty()) {
            return list[0]
        }
        return null
    }


    override fun addMedicalRecordDetail(detail: SickMedicalRecordsDetail): ResponseBody {
        sickMedicalRecordsDetailMapper.insert(detail)
        if (dateFormat(Date()) == dateFormat(detail.toDay)) {
            //通知前端刷新侧边栏
            val lastLoginHavePremUsers = companyDeptService.getLastLoginHavePremUsers(
                getContext().subCompanyId,
                Constants.UserPermCode.TODAY_RECORD
            )
            val vo = WebSocketMessageVo(
                messageType = WebSocketMessageType.REFRESH_COUNT,
                data = Constants.CountRefresh.TOMORROW_SUBSCRIBE
            )
            for (u in lastLoginHavePremUsers) {
                iSendMessageService.sendMessageToCompanyUserHaveType(
                    JSONObject(0),
                    JSONObject.toJSON(vo) as JSONObject,
                    MessageType.WEBSOCKET,
                    u.id
                )
            }
        }
        return returnSuccess()
    }

    override fun createMedicalRecords(record: SickMedicalRecords): ResponseBody {
        log.info("客户操作：==>创建就诊记录：record:{}", record)
        sickMedicalRecordsMapper.insert(record)
        return returnSuccess()
    }

    override fun createOrder(
        order: PayCustomerOrder
    ): ResponseBody {

        log.info("客户操作：==>创建订单：order:{}", order)
        order.orderNum =
            iSysNumGeneratorService.createPayLogNum(
                getContext().companyId,
                TypeEnum.SYS_NUM_GENERATOR_ORDER,
                null
            ).numShow
        payCustomerOrderMapper.insert(order)

        //通知前端刷新侧边栏
        val lastLoginHavePremUsers = companyDeptService.getLastLoginHavePremUsers(
            getContext().subCompanyId,
            Constants.UserPermCode.CHARGE_ORDER
        )
        val vo = WebSocketMessageVo(
            messageType = WebSocketMessageType.REFRESH_COUNT,
            data = Constants.CountRefresh.CHARGE_ORDER
        )
        for (u in lastLoginHavePremUsers) {
            iSendMessageService.sendMessageToCompanyUserHaveType(
                JSONObject(0),
                JSONObject.toJSON(vo) as JSONObject,
                MessageType.WEBSOCKET,
                u.id
            )
        }

        return returnSuccess()

    }


    override fun getOrderPage(vo: PayCustomerOrderSelectVo): Page<PayCustomerOrder> {
        log.info("客户操作：==>获取用户的订单分页：page:{};vo:{}", vo)
        if (vo.customerId == null) {
            return Page(vo.current, vo.size)
        }
        return payCustomerOrderMapper.getOrderPage(Page(vo.current, vo.size), vo)
    }

    override fun getOrderList(vo: PayCustomerOrderSelectVo): List<PayCustomerOrder> {
        log.info("客户操作：==>获取用户的订单列表：vo:{}", vo)
        if (vo.customerId == null) {
            return mutableListOf()
        }
        return payCustomerOrderMapper.getOrderList(vo)
    }

    override fun getCustomerMoneyFlowList(vo: PayCustomerMoneyFlowSelectVo): List<PayCustomerMoneyFlow> {
        return payCustomerMoneyFlowMapper.getList(vo)
    }

    override fun getCustomerMoneyFlowByAssociateId(associateId: Long, typeEnum: TypeEnum): List<PayCustomerMoneyFlow> {
        return payCustomerMoneyFlowMapper.selectList(QueryWrapper<PayCustomerMoneyFlow?>()
            .eq("associate_id",associateId)
            .eq("use_type",typeEnum)
        )
    }

    override fun getBalanceToMoneyLogBYAssociateId(
        associateId: Long,
        useType: TypeEnum
    ): List<PayCustomerBalanceToMoneyLog> {
       return payCustomerBalanceToMoneyLogMapper.selectList(QueryWrapper<PayCustomerBalanceToMoneyLog?>()
           .eq("associate_id",associateId)
           .eq("use_type",useType)
       )
    }

    override fun getOnGoingRecord(customerId: Long): List<SickMedicalRecords> {
        log.info("客户操作：==>获取用户正在执行的就诊记录：customerId:{}", customerId)
        return sickMedicalRecordsMapper.selectList(
            Wrappers.query<SickMedicalRecords?>()
                .eq("status", Status.ONGOING)
                .eq("customer_id", customerId)
                .orderByDesc("start_time")
        )
    }

    override fun getRecordPage(
        page: Page<SickMedicalRecords>,
        vo: SickMedicalRecordsSelectVo
    ): Page<SickMedicalRecords> {
        log.info("客户操作：==>获取用户的就诊记录分页：page:{};vo:{}", page, vo)
        return sickMedicalRecordsMapper.getRecordsPage(page, vo)
    }

    override fun getRecordList(vo: SickMedicalRecordsSelectVo): List<SickMedicalRecords> {
        log.info("客户操作：==>获取用户的就诊记录列表：vo:{}", vo)
        return sickMedicalRecordsMapper.getRecordsList(vo)
    }

    override fun createAccessLog(accessLog: SickCustomerAccessLog): ResponseBody {
        log.info("客户操作：==>创建随访回访计划：accessLog:{}", accessLog)
        sickCustomerAccessLogMapper.insert(accessLog)
        if (accessLog.type == TypeEnum.ACCESS_LOG_FOLLOW_UP) {
            if (dateFormat(Date()) == dateFormat(accessLog.planTime)) {
                //通知前端刷新侧边栏
                val lastLoginHavePremUsers = companyDeptService.getLastLoginHavePremUsers(
                    getContext().subCompanyId,
                    Constants.UserPermCode.FLOW_ACCESS_LOG
                )
                val vo = WebSocketMessageVo(
                    messageType = WebSocketMessageType.REFRESH_COUNT,
                    data = Constants.CountRefresh.FLOW_ACCESS_LOG
                )
                for (u in lastLoginHavePremUsers) {
                    iSendMessageService.sendMessageToCompanyUserHaveType(
                        JSONObject(0),
                        JSONObject.toJSON(vo) as JSONObject,
                        MessageType.WEBSOCKET,
                        u.id
                    )
                }
            }
        }
        return returnSuccess()
    }

    override fun createAccessLogByPlanDetail(
        plan: SickCustomerAccessLogPlan,
        standardTime: Date,
        detail: SickCustomerAccessLogPlanDetail
    ): ResponseBody {
        val consultantId =
            if (detail.dealUserType == TypeEnum.SICK_CUSTOMER_ACCESS_LOG_MODEL_DETAIL_DEAL_USER_TYPE_OTHER) {
                detail.dealUserId
            } else {
                null
            }
        val startTime = addTimeByType(standardTime, detail.timeNumber, detail.timeType)
        val sickCustomerAccessLog = SickCustomerAccessLog(
            id = 0L,
            customerId = plan.customerId,
            type = TypeEnum.ACCESS_LOG_FOLLOW_UP,
            createUserId = plan.createUserId,
            dealUserId = detail.dealUserId,
            doctorId = detail.doctorId,
            consultantId = consultantId,
            companyId = plan.companyId,
            deptId = plan.subCompanyId,
            planTime = startTime,
            accessItem = detail.accessItem,
            planContent = detail.planContent,
            planDetailId = detail.id
        )
        val createAccessLog = createAccessLog(sickCustomerAccessLog)
        if (createAccessLog.bodyIsError()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
            return createAccessLog
        }
        return returnSuccess()
    }

    override fun getNextAccessLogByPlanDetail(detail: SickCustomerAccessLogPlanDetail): SickCustomerAccessLogPlanDetail? {
        val selectList = sickCustomerAccessLogPlanDetailMapper.selectList(
            QueryWrapper<SickCustomerAccessLogPlanDetail?>().eq(
                "plan_id",
                detail.planId
            ).eq("order_num", detail.orderNum + 1)
        )
        return if(selectList == null || selectList.isEmpty()){
            null
        }else{
            selectList[0]
        }
    }

    override fun getAccessLogPage(
        page: Page<SickCustomerAccessLog>,
        vo: SickCustomerAccessLogSelectVo
    ): Page<SickCustomerAccessLog> {
        log.info("客户操作：==>获取随访分页数据：page{},vo:{}", page, vo)
        return sickCustomerAccessLogMapper.getLogPage(page, vo)
    }

    override fun getAccessLogList(
        vo: SickCustomerAccessLogSelectVo
    ): List<SickCustomerAccessLog> {
        log.info("客户操作：==>获取随访列表数据：vo:{}", vo)
        return sickCustomerAccessLogMapper.getLogList(vo)
    }

    override fun getLastCompleteAccessLog(customerId: Long, accessType: TypeEnum): SickCustomerAccessLog? {
        val selectList = sickCustomerAccessLogMapper.selectList(
            Wrappers.query<SickCustomerAccessLog?>()
                .eq("customer_id", customerId)
                .eq("type", accessType)
                .eq("status", Status.COMPLETE)
                .orderByDesc("finish_time").last("LIMIT 1")
        )
        if (selectList == null || selectList.isEmpty()) {
            return null
        }
        return selectList[0]
    }

    override fun getCustomerAccount(customerId: Long,subCompanyId: Long): PayCustomerAccount {
        log.info("客户操作：==> 获取账户：customerId{}", customerId)
        val accounts = payCustomerAccountMapper.selectList(
            QueryWrapper<PayCustomerAccount?>()
                .eq("customer_id",customerId)
                .eq("sub_company_id",subCompanyId))
        return if (accounts == null || accounts.isEmpty()) {
            val newAccount = PayCustomerAccount(
                customerId = customerId,
                subCompanyId = getContext().subCompanyId
            )
            payCustomerAccountMapper.insert(newAccount)
            newAccount
        }else{
            accounts[0]
        }
    }

    override fun topUpBalance(
        customerId: Long,
        money: Long,
        payType: TypeEnum,
        useType: TypeEnum,
        remark: String?,
        giftsOfGold: Long?,
        associatedTopId: Long?,
        payTime: Date?
    ): ResponseBody {

        log.info(
            "客户操作：==>充值：customerId{},money:{}，payType:{},giftsOfGold:{}",
            customerId, money, payType.typeName, giftsOfGold
        )
        if (money < 0) {
            return returnError(ErrorCode.DATA_SAVE_FAILED, "金额不能小于0")
        }
        val account = getCustomerAccount(customerId, getContext().subCompanyId)

        //添加余额
        payCustomerAccountMapper.addBalance(customerId,getContext().subCompanyId, money)
        val payCustomerBalanceInLog = PayCustomerBalanceInLog(
            customerId = customerId,
            money = money,
            useType = useType,
            payType = payType,
            flag = Status.COMPLETE,
            remark = remark,
            associatedTopId = associatedTopId,
            createTime = payTime ?: Date()
        )
        //添加余额充值记录
        payCustomerBalanceInLogMapper.insert(
            payCustomerBalanceInLog
        )
        val payCustomerMoneyFlow = PayCustomerMoneyFlow(
            money = money,
            balance = account.balance + money,
            customerId = customerId,
            useType = useType,
            remark = remark,
            associateId = associatedTopId,
            createTime = payTime ?: Date()
        )
        if(useType == TypeEnum.PAY_TYPE_TOP_UP){
            payCustomerMoneyFlow.associateId = payCustomerBalanceInLog.id
        }
        //添加余额变动记录
        payCustomerMoneyFlowMapper.insert(
            payCustomerMoneyFlow
        )

        if (giftsOfGold != null) {
            if (giftsOfGold < 0) {
                return returnError(ErrorCode.DATA_SAVE_FAILED, "金额不能小于0")
            }
            if (giftsOfGold != 0L) {
                payCustomerAccountMapper.addGiftsOfGold(customerId, getContext().subCompanyId, giftsOfGold)
                val payCustomerGiftsOfGold = PayCustomerGiftsOfGold(
                    money = giftsOfGold,
                    afterMoney = account.giftsOfGold + giftsOfGold,
                    customerId = customerId,
                    updateType = useType,
                    remark = remark,
                    associateId = associatedTopId
                )
                if(useType == TypeEnum.PAY_TYPE_TOP_UP){
                    payCustomerGiftsOfGold.associateId = payCustomerBalanceInLog.id
                }
                payCustomerGiftsOfGoldMapper.insert(
                    payCustomerGiftsOfGold
                )
            }
        }

        return returnSuccess()
    }

    override fun onlyAddBalance(customerId: Long,
                                money: Long,
                                useType: TypeEnum,
                                remark: String?,
                                associateId: Long?): ResponseBody {
        log.info("客户操作：==>添加余额：customerId{},money:{}，payType:{}", customerId, money, useType.typeName)
        val account = getCustomerAccount(customerId, getContext().subCompanyId)
        //添加余额
        payCustomerAccountMapper.addBalance(customerId,getContext().subCompanyId, money)
        //余额变动记录
        payCustomerMoneyFlowMapper.insert(
            PayCustomerMoneyFlow(
                money = money,
                balance = account.balance + money,
                customerId = customerId,
                useType = useType,
                remark = remark,
                associateId = associateId
            )
        )
        return returnSuccess()
    }

    override fun onlyTopBalance(customerId: Long, money: Long): ResponseBody {
        getCustomerAccount(customerId, getContext().subCompanyId)
        //添加余额
        payCustomerAccountMapper.addBalance(customerId,getContext().subCompanyId, money)
        return returnSuccess()
    }

    override fun onlySubBalance(customerId: Long, money: Long): ResponseBody {
        val account = getCustomerAccount(customerId, getContext().subCompanyId)
        if(account.balance < money){
            return returnError(ErrorCode.OPERATION_DATA_ERROR,"用户余额不足")
        }
        //添加余额
        payCustomerAccountMapper.subBalance(customerId,getContext().subCompanyId, money)
        return returnSuccess()
    }

    override fun onlyAddGiftsOfGold(customerId: Long, money: Long):ResponseBody {
        val account = getCustomerAccount(customerId, getContext().subCompanyId)
        //添加余额
        payCustomerAccountMapper.addGiftsOfGold(customerId,getContext().subCompanyId, money)
        return returnSuccess()
    }

    override fun onlySubiftsOfGold(customerId: Long, money: Long):ResponseBody {
        val account = getCustomerAccount(customerId, getContext().subCompanyId)
        if(account.giftsOfGold < money){
            return returnError(ErrorCode.OPERATION_DATA_ERROR,"用户馈赠金额不足")
        }
        //添加余额
        payCustomerAccountMapper.subGiftsOfGold(customerId,getContext().subCompanyId, money)
        return returnSuccess()
    }

    override fun subGiftsOfGold(
        customerId: Long,
        associateId: Long?,
        money: Long,
        updateType: TypeEnum,
        remark: String?
    ): ResponseBody {
        val account = getCustomerAccount(customerId, getContext().subCompanyId)
        if (money < 0) {
            return returnError(ErrorCode.DATA_SAVE_FAILED, "金额不能小于0")
        }
        if (money != 0L) {
            if (money > account.giftsOfGold) {
                return returnError(ErrorCode.OPERATION_DATA_ERROR, "余额不足")
            }
            payCustomerAccountMapper.subGiftsOfGold(customerId,getContext().subCompanyId, money)
            payCustomerGiftsOfGoldMapper.insert(
                PayCustomerGiftsOfGold(
                    money = money,
                    associateId = associateId,
                    afterMoney = account.giftsOfGold - money,
                    customerId = customerId,
                    updateType = updateType,
                    remark = remark
                )
            )
        }
        return returnSuccess()
    }

    override fun balanceToMoney(
        customerId: Long,
        money: Long,
        useType: TypeEnum,
        payType: TypeEnum,
        remark: String?,
        giftsOfGold: Long?,
        associateId: Long?
    ): ResponseBody {
        log.info(
            "客户操作：==> 余额转现金：customerId{},money:{}，useType:{},giftsOfGold:{}",
            customerId, money, useType.typeName, giftsOfGold
        )
        val account = getCustomerAccount(customerId, getContext().subCompanyId)
        if (account.balance < money) {
            return returnError(ErrorCode.OPERATION_DATA_ERROR, "余额不足")
        }
        //扣除余额
        payCustomerAccountMapper.subBalance(customerId,getContext().subCompanyId, money)

        //患者退款记录
        payCustomerBalanceToMoneyLogMapper.insert(
            PayCustomerBalanceToMoneyLog(
                id = 0L,
                customerId = customerId,
                useType = useType,
                money = money,
                payType = payType,
                associateId = associateId
            )
        )

        val payCustomerMoneyFlow = PayCustomerMoneyFlow(
            money = money,
            balance = account.balance - money,
            customerId = customerId,
            useType = useType,
            remark = remark,
            associateId = associateId
        )
        //添加余额变动记录
        payCustomerMoneyFlowMapper.insert(
            payCustomerMoneyFlow
        )
        if (giftsOfGold != null) {
            if (giftsOfGold < 0) {
                return returnError(ErrorCode.DATA_SAVE_FAILED, "馈赠金不能小于0")
            }
            if (giftsOfGold > account.giftsOfGold) {
                return returnError(ErrorCode.OPERATION_DATA_ERROR, "馈赠金不足")
            }
            if (giftsOfGold != 0L) {
                payCustomerAccountMapper.subGiftsOfGold(customerId,getContext().subCompanyId, giftsOfGold)
                payCustomerGiftsOfGoldMapper.insert(
                    PayCustomerGiftsOfGold(
                        money = giftsOfGold,
                        associateId = payCustomerMoneyFlow.id,
                        afterMoney = account.giftsOfGold - giftsOfGold,
                        customerId = customerId,
                        updateType = useType,
                        remark = remark
                    )
                )
            }
        }
        return returnSuccess()
    }

    override fun balanceToOtherCustomer(
        customerId: Long,
        toCustomerId: Long,
        money: Long,
        remark: String?,
        giftsOfGold: Long?
    ): ResponseBody {
        log.info(
            "客户操作：==>余额转账：customerId{},toCustomerId:{}，money:{},giftsOfGold:{}",
            customerId, toCustomerId, money, giftsOfGold
        )
        if (money < 0) {
            return returnError(ErrorCode.DATA_SAVE_FAILED, "金额不能小于0")
        }
        val account = getCustomerAccount(customerId, getContext().subCompanyId)
        if (account.balance < money) {
            return returnError(ErrorCode.OPERATION_DATA_ERROR, "余额不足")
        }
        if (account.giftsOfGold < giftsOfGold?:0L) {
            return returnError(ErrorCode.OPERATION_DATA_ERROR, "馈赠金不足")
        }
        //添加转账记录
        val payCustomerBalanceToCustomerLog = PayCustomerBalanceToCustomerLog(
            id = 0,
            customerId = customerId,
            toCustomerId = toCustomerId,
            money = money,
            giftsOfGold = giftsOfGold ?: 0
        )
        payCustomerBalanceToCustomerLogMapper.insert(
            payCustomerBalanceToCustomerLog
        )
        //扣除余额
        payCustomerAccountMapper.subBalance(customerId,getContext().subCompanyId, money)
        //添加余额变动记录
        val payCustomerMoneyFlow = PayCustomerMoneyFlow(
            money = money,
            balance = account.balance - money,
            customerId = customerId,
            useType = TypeEnum.PAY_TYPE_BALANCE_TRANSFER_SUB,
            remark = remark,
            associateId = payCustomerBalanceToCustomerLog.id
        )
        payCustomerMoneyFlowMapper.insert(
            payCustomerMoneyFlow
        )
        if (giftsOfGold != null && giftsOfGold != 0L) {
            if (giftsOfGold < 0) {
                return returnError(ErrorCode.DATA_SAVE_FAILED, "金额不能小于0")
            }
            if (giftsOfGold > account.giftsOfGold) {
                return returnError(ErrorCode.OPERATION_DATA_ERROR, "馈赠金不足")
            }
            if (money != 0L) {
                payCustomerAccountMapper.subGiftsOfGold(customerId,getContext().subCompanyId, giftsOfGold)
                payCustomerGiftsOfGoldMapper.insert(
                    PayCustomerGiftsOfGold(
                        money = giftsOfGold,
                        associateId = payCustomerBalanceToCustomerLog.id,
                        afterMoney = account.giftsOfGold - giftsOfGold,
                        customerId = customerId,
                        updateType = TypeEnum.PAY_TYPE_BALANCE_TRANSFER_SUB,
                        remark = remark,

                    )
                )
            }
        }


        val toCustomerAccount = getCustomerAccount(toCustomerId, getContext().subCompanyId)
        //添加余额
        payCustomerAccountMapper.addBalance(toCustomerId,getContext().subCompanyId, money)
        //余额变动记录
        payCustomerMoneyFlowMapper.insert(
            PayCustomerMoneyFlow(
                money = money,
                balance = toCustomerAccount.balance + money,
                customerId = customerId,
                useType = TypeEnum.PAY_TYPE_BALANCE_TRANSFER_TOP,
                remark = remark,
                associateId = payCustomerBalanceToCustomerLog.id,
            )
        )


        if (giftsOfGold != null) {
            if (giftsOfGold != 0L) {
                payCustomerAccountMapper.addGiftsOfGold(customerId,getContext().subCompanyId, giftsOfGold)
                payCustomerGiftsOfGoldMapper.insert(
                    PayCustomerGiftsOfGold(
                        money = giftsOfGold,
                        associateId = payCustomerBalanceToCustomerLog.id,
                        afterMoney = toCustomerAccount.giftsOfGold + giftsOfGold,
                        customerId = toCustomerId,
                        updateType = TypeEnum.PAY_TYPE_BALANCE_TRANSFER_TOP,
                        remark = remark
                    )
                )
            }
        }


        return returnSuccess()
    }

    override fun topUpIntegral(customerId: Long, integral: Long, remark: String?): ResponseBody {
        log.info("客户操作：==>积分添加：customerId{},integral:{}，remark:{}", customerId, integral, remark)

        val customerAccount = getCustomerAccount(customerId, getContext().subCompanyId)
        payCustomerAccountMapper.addIntegral(customerId,getContext().subCompanyId, integral)
        payCustomerIntegralFlowMapper.insert(
            PayCustomerIntegralFlow(
                integral = integral,
                balance = customerAccount.balance + integral,
                customerId = customerId,
                useType = TypeEnum.PAY_TYPE_TOP_UP,
                remark = remark
            )
        )
        return returnSuccess()
    }

    override fun addAmountOwed(customerId: Long, amountOwed: Long, remark: String?): ResponseBody {
        log.info("客户操作：==>添加欠款：customerId{},amountOwed:{}，remark:{}", customerId, amountOwed, remark)
        //防止客户没有账户，获取一次如果没有会添加
        getCustomerAccount(customerId, getContext().subCompanyId)
        payCustomerAccountMapper.addAmountOwed(customerId,getContext().subCompanyId, amountOwed)
        return returnSuccess()
    }

    override fun subAmountOwed(customerId: Long, amountOwed: Long, remark: String?): ResponseBody {
        log.info("客户操作：==>扣除欠款：customerId{},amountOwed:{}，remark:{}", customerId, amountOwed, remark)
        //防止客户没有账户，获取一次如果没有会添加
        getCustomerAccount(customerId, getContext().subCompanyId)
        payCustomerAccountMapper.subAmountOwed(customerId,getContext().subCompanyId, amountOwed)
        return returnSuccess()
    }

    override fun getCustomerOrderSumMoney(customerId: Long,subCompanyId: Long?): Long {
        log.info("客户操作：==> 获取用户订单消费总额：customerId{}", customerId)
        return payCustomerOrderMapper.getSumMoney(customerId, subCompanyId, getContext().companyId)
    }

    override fun getCustomerOrderAmountSumMoney(customerId: Long, subCompanyId: Long?): Long {
        log.info("客户操作：==> 获取用户订单付款总额：customerId{}", customerId)
        return payCustomerOrderMapper.getCustomerOrderAmountSumMoney(customerId, subCompanyId, getContext().companyId)
    }

    override fun getCustomerPaySumMoney(customerId: Long, subCompanyId: Long?): Long {
        log.info("客户操作：==> 获取客户支付总额：customerId{}", customerId)
        return payCustomerMoneyFlowMapper.selectCustomerPaySumMoney(
            getContext().companyId,
            TypeEnum.PAY_TYPE_PAY_ORDER, customerId, subCompanyId
        )
    }

    override fun getCustomerCouponsList(vo: PayCustomerCouponsSelectVo): List<PayCustomerCoupons> {
        log.info("客户操作：==> 获取优惠卷列表：vo{}", vo)
        return payCustomerCouponsMapper.getCustomerCoupons(vo)
    }

    override fun addCouponsToCustomer(couponsId: Long, customerId: Long, count: Int): ResponseBody {
        val model =
            payCompanyCouponsModelMapper.selectById(couponsId) ?: return returnError(
                ErrorCode.DATA_IS_NOT_FIND,
                "未找到该优惠券"
            )
        if (model.showStatus == 0) {
            return returnError(ErrorCode.COUPONS_TO_CUSTOMER_ERROR, "优惠劵未启用")
        }
        val startTime: Date
        val endTime: Date
        if (model.timeType == TypeEnum.CUSTOMER_COUPONS_TIME_TYPE_AFTER_DAY_TO_DAY) {
            val c = Calendar.getInstance()
            c.time = Date()
            c.add(Calendar.DAY_OF_MONTH, model.startTimeDay)
            startTime = c.time
            c.time = Date()
            c.add(Calendar.DAY_OF_MONTH, model.endTimeDay)
            endTime = c.time
        } else {
            startTime = model.startTime!!
            endTime = model.endTime!!
        }

        for (i in 1..count) {
            val payCustomerCoupons = PayCustomerCoupons(
                title = model.title,
                content = model.content,
                type = model.type,
                startTime = startTime,
                endTime = endTime,
                deptId = model.deptId,
                customerId = customerId,
                modelId = model.id
            )
            payCustomerCoupons.other = model.other
            payCustomerCouponsMapper.insert(
                payCustomerCoupons
            )
        }
        return returnSuccess()
    }

    override fun addSubscribeLog(subscribeLog: CustomerSubscribeLog): ResponseBody {
        log.info("客户操作：==> 添加一个预约：subscribeLog{}", subscribeLog)
        setTimeTo15Min(subscribeLog.subscribeTime)
        customerSubscribeLogMapper.insert(subscribeLog)

        iCompanyUserOperationLogService.addLog(
            associatedId = subscribeLog.id,
            modelType = TypeEnum.COMPANY_USER_OPERATION_LOG_MODEL_TYPE_RECORD,
            tableType = TypeEnum.COMPANY_USER_OPERATION_LOG_TABLE_TYPE_SUBSCRIBE_LOG,
            updateType = TypeEnum.COMPANY_USER_OPERATION_LOG_UPDATE_TYPE_NEW_ADD,
            beforeObj = null,
            afterObj = subscribeLog,
            customerId = subscribeLog.customerId,
            createUserId = getContext().userId
        )

        if (dateFormat(getDayAdd(Date(), 1)) == dateFormat(subscribeLog.subscribeTime)) {
            //通知前端刷新侧边栏
            val lastLoginHavePremUsers = companyDeptService.getLastLoginHavePremUsers(
                getContext().subCompanyId,
                Constants.UserPermCode.TOMORROW_SUBSCRIBE
            )
            val vo = WebSocketMessageVo(
                messageType = WebSocketMessageType.REFRESH_COUNT,
                data = Constants.CountRefresh.TOMORROW_SUBSCRIBE
            )
            for (u in lastLoginHavePremUsers) {
                iSendMessageService.sendMessageToCompanyUserHaveType(
                    JSONObject(0),
                    JSONObject.toJSON(vo) as JSONObject,
                    MessageType.WEBSOCKET,
                    u.id
                )
            }
        }
        if (subscribeLog.subscribeType == TypeEnum.CUSTOMER_SUBSCRIBE_TYPE_UNDETERMINDED) {
            val lastLoginHavePremUsers = companyDeptService.getLastLoginHavePremUsers(
                getContext().subCompanyId,
                Constants.UserPermCode.UNDETERMINED_SUBSCRIBE
            )
            //取消预约刷新
            val undeterminedVo = WebSocketMessageVo(
                messageType = WebSocketMessageType.REFRESH_COUNT,
                data = Constants.CountRefresh.UNDETERMINED_SUBSCRIBE
            )
            for (u in lastLoginHavePremUsers) {
                iSendMessageService.sendMessageToCompanyUserHaveType(
                    JSONObject(0),
                    JSONObject.toJSON(undeterminedVo) as JSONObject,
                    MessageType.WEBSOCKET,
                    u.id
                )
            }
        }
        return returnSuccess()
    }

    override fun refreshLastRecordsDetailId(customerId: Long): ResponseBody {
        val lastRecordsDetail = getLastRecordsDetail(customerId)
        if (lastRecordsDetail != null) {
            customerInfoMapper.update(
                null, Wrappers.update<CustomerInfo?>()
                    .eq("id", customerId).set("last_record_detail_id", lastRecordsDetail.id)
            )
        }
        return returnSuccess()
    }

    override fun getLastRecordsDetail(customerId: Long): SickMedicalRecordsDetail? {
        log.info("客户操作：==> 获取最后一次就诊记录明细：customerId{}", customerId)
        return sickMedicalRecordsDetailMapper.getLastRecordsDetailOpen(customerId)
    }

    override fun getCustomerRecordsDetailList(vo: SickMedicalRecordsDetailSelectVo): List<SickMedicalRecordsDetail> {
        log.info("客户操作：==> 获取就诊记录明细列表：vo{}", vo)
        return sickMedicalRecordsDetailMapper.getList(vo)
    }

    override fun getCustomerRecordsDetailPage(
        page: Page<SickMedicalRecordsDetail>,
        vo: SickMedicalRecordsDetailSelectVo
    ): Page<SickMedicalRecordsDetail> {
        log.info("客户操作：==> 获取就诊记录明细列表：vo{}", vo)
        return sickMedicalRecordsDetailMapper.getPage(page, vo)
    }

    override fun getCustomerSubscribeLogPage(vo: CustomerSubscribeLogSelectVo): Page<CustomerSubscribeLog> {
        val page = Page<CustomerSubscribeLog>(vo.current, vo.size)
        if (vo.customerId == null) {
            return page
        }
        val resPage = customerSubscribeLogMapper.getSubscribeLogPage(page, vo)
        for (i in resPage.records) {
            if (!i.itemIdsShow.isNullOrEmpty()) {
                i.itemNames = iCustomerSubscribeLogService.getSubscribeItemsByIdsStr(i.itemIdsShow!!)
            }
        }

        return resPage
    }

    override fun getToDayCustomerSubscribeLog(customerId: Long, subCompanyId: Long): CustomerSubscribeLog? {
        log.info("客户操作：==> 获取当天的预约记录：customerId{}，subCompanyId：{}", subCompanyId)
        val customerToDayLog = customerSubscribeLogMapper.getCustomerToDayLog(customerId, subCompanyId)
        if (customerToDayLog.isEmpty()) {
            return null
        }
        return customerToDayLog[0]
    }

    override fun getCustomerToDayLogNotHaveRecord(customerId: Long, subCompanyId: Long): CustomerSubscribeLog? {
        log.info("客户操作：==> 获取当天的预约记录：customerId{}，subCompanyId：{}", subCompanyId)
        val customerToDayLog = customerSubscribeLogMapper.getCustomerToDayLogNotHaveRecord(customerId, subCompanyId)
        if (customerToDayLog.isEmpty()) {
            return null
        }
        return customerToDayLog[0]
    }


    override fun getLatelySubscribeLog(customerId: Long, companyId: Long, subCompanyId: Long?): CustomerSubscribeLog? {
        val todayFirstTime = Date()
        setDayFirstTime(todayFirstTime)
        val subscribeLogList = customerSubscribeLogMapper.getSubscribeLogList(
            CustomerSubscribeLogSelectVo(
                customerId = customerId,
                subCompanyId = subCompanyId,
                afterPlanTime = todayFirstTime
            )
        )
        if (subscribeLogList.isEmpty()) {
            return null
        }
        return subscribeLogList[subscribeLogList.size - 1]
    }

    override fun pay(
        customerId: Long,
        money: Long,
        useType: TypeEnum,
        associateId: Long?,
        remark: String?,
        payTime: Date?
    ): ResponseBody {

        log.info(
            "用户管理 ==> 付款 :customerId:$customerId," +
                    "money:$money，useType：$useType, associateId:$associateId,remark$remark"
        )
        val customerAccount = getCustomerAccount(customerId, getContext().subCompanyId)
        //处理付款方式（余额还是馈赠金额）
        var payGiftsOfGold = 0L
        val payMoney =
            if (money > customerAccount.balance) {
                if (money > customerAccount.balance + customerAccount.giftsOfGold) {
                    return returnError(ErrorCode.OPERATION_DATA_ERROR, "用户余额不足")
                } else {
                    payGiftsOfGold = money - customerAccount.balance
                }
                customerAccount.balance
            } else {
                money
            }

        payCustomerAccountMapper.subBalance(customerId,getContext().subCompanyId, payMoney)
        payCustomerMoneyFlowMapper.insert(
            PayCustomerMoneyFlow(
                associateId = associateId,
                money = payMoney,
                balance = customerAccount.balance - payMoney,
                customerId = customerId,
                useType = useType,
                remark = remark,
                createTime = payTime ?: Date()
            )
        )
        if (payGiftsOfGold != 0L) {
            payCustomerAccountMapper.subGiftsOfGold(customerId,getContext().subCompanyId, payGiftsOfGold)

            payCustomerGiftsOfGoldMapper.insert(
                PayCustomerGiftsOfGold(
                    associateId = associateId,
                    money = payGiftsOfGold,
                    afterMoney = customerAccount.giftsOfGold - payGiftsOfGold,
                    customerId = customerId,
                    updateType = useType,
                    createTime = payTime ?: Date(),
                    remark = remark
                )
            )
        }
        val res = JSONObject()
        res["payMoney"] = payMoney
        res["payGiftsOfGold"] = payGiftsOfGold


        return returnSuccess(res)
    }

    override fun getGiftsOfGold(associateId:Long,updateType: TypeEnum):List<PayCustomerGiftsOfGold>{
        return payCustomerGiftsOfGoldMapper.selectList(QueryWrapper<PayCustomerGiftsOfGold?>()
            .eq("associate_id",associateId)
            .eq("update_type",updateType))
    }

    override fun addMedicalHistory(medicalHistory: SickMedicalHistory): ResponseBody {
        log.info("用户管理 ==> 添加病历 :medicalHistory:$medicalHistory,")
        if (medicalHistory.recordId == null) {
            val onGoingRecord = getOnGoingRecord(medicalHistory.customerId)
            if (onGoingRecord.isNotEmpty()) {
                medicalHistory.recordId = onGoingRecord[0].id
            }
        }

        sickMedicalHistoryMapper.insert(medicalHistory)
        val customerRecordsDetailList =
           getCustomerRecordsDetailList(
                SickMedicalRecordsDetailSelectVo(
                    customerId = medicalHistory.customerId,
                    day = medicalHistory.seeDoctorTime,
                    deptId = getContext().subCompanyId
                )
            )
        if(customerRecordsDetailList.isNotEmpty()){
            val oldDetail = customerRecordsDetailList[0]
             iSickMedicalRecordsService.detailToStatus(SickMedicalRecordsDetailToStatusVo(id = oldDetail.id,Status.COMPLETE_TREATMENT))
            iSickMedicalRecordsService.detailSetHistoryId(oldDetail.id,medicalHistory.id)
            if(oldDetail.subscribeLogId != null){
                val subLog = customerSubscribeLogMapper.selectById(oldDetail.subscribeLogId)
                if(subLog != null){
                    subLog.historyId = medicalHistory.id
                    customerSubscribeLogMapper.updateById(subLog)
                }
            }

        }
        iCompanyUserOperationLogService.addLog(
            associatedId = medicalHistory.id,
            modelType = TypeEnum.COMPANY_USER_OPERATION_LOG_MODEL_TYPE_RECORD,
            tableType = TypeEnum.COMPANY_USER_OPERATION_LOG_TABLE_TYPE_MEDICAL_HISTORY,
            updateType = TypeEnum.COMPANY_USER_OPERATION_LOG_UPDATE_TYPE_NEW_ADD,
            beforeObj = null,
            afterObj = medicalHistory,
            customerId = medicalHistory.customerId,
            createUserId = getContext().userId
        )
        return returnSuccess()
    }

    override fun getMedicalHistoryList(vo: SickMedicalHistorySelectVo): List<SickMedicalHistory> {
        if (vo.customerId == null && vo.recordId == null) {
            return listOf()
        }
        return sickMedicalHistoryMapper.getHistoryList(vo)
    }


    override fun addImage(image: SickCustomerImage): ResponseBody {
        log.info("客户操作：==>添加图片：image:{}", image)
        sickCustomerImageMapper.insert(image)
        return returnSuccess()
    }

    override fun getImageList(customerId: Long, vo: SickCustomerImageSelectVo): List<SickCustomerImage> {

        log.info("客户操作 ==> 查询客户图片customerId{}, vo:{}", customerId, vo)
        if (vo.customerId == null) {
            vo.customerId = customerId
        }
        return sickCustomerImageMapper.selectList(vo)
    }

    override fun delImage(id: Long): ResponseBody {
        val sickCustomerImage =
            sickCustomerImageMapper.selectById(id) ?: return returnError(ErrorCode.DATA_IS_NOT_FIND, "未找到图片，请刷新重试")

        if(sickCustomerImage.localPath != null){
            try {
                val file = File(sickCustomerImage.localPath!!)
                if(file.exists()){
                    file.delete()
                }
            }catch (e:Exception){
                e.printStackTrace()
            }
        }
        sickCustomerImageMapper.deleteById(id)
        return returnSuccess()
    }

    override fun getOrderDetailList(
        customerId: Long,
        vo: PayCustomerOrderDetailSelectVo
    ): List<PayCustomerOrderDetail> {
        if (vo.customerId == null) {
            vo.customerId = customerId
        }
        return payCustomerOrderDetailMapper.getDetailList(vo)
    }

    override fun getCustomOrderList(id: Long): List<PayCustomOrderProcessVo> {
        return payCustomerOrderMapper.getCustomOrderList(id)
    }

    override fun getCustomerLastOrder(customerId: Long, vo: PayCustomerOrderSelectVo): PayCustomerOrder? {
        vo.customerId = customerId
        return payCustomerOrderMapper.getLastOrder(vo)
    }

    override fun addVisitByOrder(customerId: Long, deptId: Long, order: PayCustomerOrder): ResponseBody {

        val itemIds = mutableSetOf<Long>()
        if (order.details == null || order.details!!.isEmpty()) {
            return returnSuccess()
        }
        for (detail in order.details!!) {
            //同样的项目，加一次回访就好了
            if (itemIds.contains(detail.itemId)) {
                continue
            }
            itemIds.add(detail.itemId)

            val list = iSysCompanyPayItemService.getVisitConfig(detail.itemId, order.deptId)
            if (list != null && list.isNotEmpty()) {
                val c = Calendar.getInstance()
                c.time = Date()
                for (visitSetting in list) {
                    c.add(Calendar.DAY_OF_MONTH, visitSetting.intervals)
                    val accessLog = SickCustomerAccessLog(
                        id = 0L,
                        customerId = customerId,
                        dealUserId = detail.doctorId?: getContext().userId,
                        startTime = c.time,
                        endTime = c.time,
                        status = Status.WAIT_AUDIT,
                        planTime = c.time,
                        planContent = visitSetting.content,
                        orderDetailId = detail.id,
                        numberOfTimes = visitSetting.numberOfTimes,
                        doctorId = detail.doctorId?:getContext().userId,
                        consultantId = order.secondaryUserId
                    )
                    createAccessLog(accessLog)
                }
            }
        }
        return returnSuccess()
    }

    override fun addOperatorLogByOrder(customerId: Long, deptId: Long, order: PayCustomerOrder): ResponseBody {
        val itemIds = mutableSetOf<Long>()
        if (order.details == null || order.details!!.isEmpty()) {
            return returnSuccess()
        }
        for (detail in order.details!!) {
            //同样的项目，加一次回访就好了
            if (itemIds.contains(detail.itemId)) {
                continue
            }
            itemIds.add(detail.itemId)

            val list = iSysCompanyPayItemService.getOperatorConfig(detail.itemId, order.deptId)
            if (list != null && list.isNotEmpty()) {
                val c = Calendar.getInstance()
                c.time = Date()
                for (opeSetting in list) {
                    c.add(Calendar.DAY_OF_MONTH, opeSetting.intervals)
                    val operatorLog = PayCustomerOrderItemOperatorLog(
                        id = 0,
                        itemId = detail.itemId,
                        detailId = detail.id,
                        customerId = order.customerId,
                        planTime = c.time,
                        planContent = opeSetting.content,
                        chargeUserId = detail.doctorId ?: getContext().userId,
                        numberOfTimes = opeSetting.numberOfTimes
                    )
                    addOperatorLog(operatorLog)
                }
            }
        }
        return returnSuccess()
    }

    override fun addOperatorLog(operatorLog: PayCustomerOrderItemOperatorLog): ResponseBody {
        log.info("客户管理 ==> 添加订单项目就诊记录 log：{}", operatorLog)
        payCustomerOrderItemOperatorLogMapper.insert(operatorLog)
        return returnSuccess()
    }

    override fun getShowRuleByOrderDetail(customerId: Long, subCompanyId: Long): List<PayItemCustomerShowRule> {
        val customerOrderDetailShowRule =
            payCustomerOrderDetailMapper.getCustomerOrderDetailShowRule(customerId, subCompanyId)
        val resList = mutableListOf<PayItemCustomerShowRule>()
        for (vo in customerOrderDetailShowRule) {
            if (vo.rules != null && vo.rules.isNotEmpty()) {
                resList.add(vo.rules[0])
            }
        }
        return resList
    }

    override fun getProcessingPage(vo: TechnologyProcessingMapperVo): Page<TechnologyProcessing> {
        log.info("技加工记录对象：，vo：{}", vo)
        val page = Page<TechnologyProcessing>(vo.current, vo.size)
        val processListByPage = technologyProcessingMapper.getProcessListByPage(page, vo)
        val record = processListByPage.records
        for (i in record) {
            i.details = iTechnologyProcessingService.processDetail(i.id)
        }
        return processListByPage
    }

    override fun customerHaveArrearsOrder(customerId: Long): Boolean {
        return payCustomerOrderMapper.getCountByCharge(
            PayCustomOrderToChargeVo(
                customerId = customerId,
                status = Status.PAYING
            )
        ) != 0
    }


    override fun getCustomerSecondSourceList(
        companyId: Long,
        parentValue: String?
    ): List<CustomerInfoSecondSource> {

        val wrapper = QueryWrapper<CustomerInfoSecondSource>()
        wrapper.eq("company_id", companyId)
        wrapper.eq("enabled", 1)
        if (parentValue != null && parentValue.isNotEmpty()) {
            wrapper.eq("parent_value", parentValue)
        }
        wrapper.orderByAsc("order_num")
        return customerInfoSecondSourceMapper.selectList(wrapper)
    }

    override fun getCustomerSecondSourceById(id: Long): CustomerInfoSecondSource? {
        return customerInfoSecondSourceMapper.selectById(id)
    }

    override fun addCustomerSecondSource(dist: CustomerInfoSecondSource): ResponseBody {
        customerInfoSecondSourceMapper.insert(dist)
        return returnSuccess()
    }

    override fun updateCustomerSecondSource(dist: CustomerInfoSecondSource): ResponseBody {
        customerInfoSecondSourceMapper.updateById(dist)
        return returnSuccess()
    }

    override fun delCustomerSecondSource(id: Long): ResponseBody {
        val source = customerInfoSecondSourceMapper.selectById(id) ?: return returnError(
            ErrorCode.OPERATION_DATA_ERROR,
            "未找到类型，请刷新重试"
        )
        //先把子类型给删除了
        customerInfoSourceDistMapper.update(
            null,
            Wrappers.update<CustomerInfoSourceDist?>().set("enabled", 0).eq("parent_id", id)
        )

        source.enabled = 0
        customerInfoSecondSourceMapper.updateById(source)
        return returnSuccess()
    }

    override fun getCustomerSourceDistList(companyId: Long, parentId: Long?): List<CustomerInfoSourceDist> {
        val wrapper = QueryWrapper<CustomerInfoSourceDist>()
        wrapper.eq("company_id", companyId)
        wrapper.eq("enabled", 1)
        if (parentId != null) {
            wrapper.eq("parent_id", parentId)
        }
        wrapper.orderByAsc("order_num")
        return customerInfoSourceDistMapper.selectList(wrapper)
    }

    override fun addCustomerSourceDist(dist: CustomerInfoSourceDist): ResponseBody {
        customerInfoSourceDistMapper.insert(dist)
        return returnSuccess()
    }

    override fun updateCustomerSourceDist(dist: CustomerInfoSourceDist): ResponseBody {
        customerInfoSourceDistMapper.updateById(dist)
        return returnSuccess()
    }

    override fun delCustomerSourceDist(id: Long): ResponseBody {
        val dist = customerInfoSourceDistMapper.selectById(id) ?: return returnError(
            ErrorCode.OPERATION_DATA_ERROR,
            "未找到类型，请刷新重试"
        )
        dist.enabled = 0
        customerInfoSourceDistMapper.updateById(dist)
        return returnSuccess()
    }

    override fun addPayOrderLog(payLog: PayOrderCustomerPayLog): ResponseBody {
        if (payLog.details == null || payLog.details!!.isEmpty()) {
            //无效的订单付款，所以不用加记录
            return returnSuccess()
        }
        //先验证
        var paySumMoney = 0L
        for (detail in payLog.details!!) {
            if (detail.payMoney < 0) {
                return returnError(ErrorCode.OPERATION_DATA_ERROR, "付款金额不能未负数")
            }
            paySumMoney += detail.payMoney
        }
        payLog.payNum = iSysNumGeneratorService.createPayLogNum(
            getContext().companyId, TypeEnum.SYS_NUM_GENERATOR_PAY_LOG,
            getContext().subCompanyId
        ).numShow
        payOrderCustomerPayLogMapper.insert(payLog)
        for (detail in payLog.details!!) {
            detail.payLogId = payLog.id
            payOrderCustomerPayLogDetailMapper.insert(detail)
        }
        return returnSuccess()
    }

    @Autowired
    private lateinit var companyUserService: ICompanyUserService

    override fun sendNoticeConfig(companyId: Long, customerId: Long, name: String): JSONObject? {
        val company = companyUserService.getCacheCompany(companyId) ?: return null
        val customer = getById(customerId) ?: return null
        val messageConfig = company.getMessageConfig(name) ?: return null
        when (name) {
            "SMS_BY_253" -> {
                getMobileFirstStr(customer)
                messageConfig["mobilePhone"] = customer.mobileFirstNum
            }
            "WEBSOCKET" -> {
                messageConfig["userId"] = customer.id
            }
            "TENCENT_SMS" -> {
                getMobileFirstStr(customer)
                messageConfig["mobilePhone"] = customer.mobileFirstNum
            }
        }
        return messageConfig
    }

    override fun getCustomerFirstSickDoctor(customerId: Long): CompanyUser? {
        val lastRecord = sickMedicalRecordsMapper.getLastRecordByCustomerId(customerId) ?: return null
        if (lastRecord.doctorId == null) {
            return null
        }
        return iCompanyUserService.getUser(lastRecord.doctorId!!)
    }

    override fun getCustomerSickDoctor(customerId: Long): CompanyUser? {
        val lastRecordsDetail = sickMedicalRecordsDetailMapper.getLastRecordsDetailOpen(customerId) ?: return null
        if (lastRecordsDetail.masterUserId == null) {
            return null
        }
        return iCompanyUserService.getUser(lastRecordsDetail.masterUserId!!)
    }

    override fun getCustomerResponsibilityDoctor(customerId: Long): CompanyUser? {
        val selectList = customerDeptConfigMapper.selectList(
            QueryWrapper<CustomerDeptConfig?>().eq("customer_id", customerId).eq(
                "dept_id",
                getContext().subCompanyId
            )
        )
        if (selectList == null || selectList.isEmpty()) {
            return null
        }
        val config = selectList[0]
        if (config.firstChargeUserId == null) {
            return null
        }
        return iCompanyUserService.getUser(config.firstChargeUserId!!)
    }

    override fun getCustomerFirstSickConsultant(customerId: Long): CompanyUser? {
        val lastRecord = sickMedicalRecordsMapper.getLastRecordByCustomerId(customerId) ?: return null
        val firstRecordsDetailOpenByRecord =
            sickMedicalRecordsDetailMapper.getFirstRecordsDetailOpenByRecord(lastRecord.id) ?: return null
        if (firstRecordsDetailOpenByRecord.secondaryUserId == null) {
            return null
        }
        return iCompanyUserService.getUser(firstRecordsDetailOpenByRecord.secondaryUserId!!)
    }

    override fun getCustomerSickConsultant(customerId: Long): CompanyUser? {
        val lastRecordsDetail = sickMedicalRecordsDetailMapper.getLastRecordsDetailOpen(customerId) ?: return null
        if (lastRecordsDetail.secondaryUserId == null) {
            return null
        }
        return iCompanyUserService.getUser(lastRecordsDetail.secondaryUserId!!)
    }

    override fun getCustomerConsultant(customerId: Long): CompanyUser? {
        val selectList = customerDeptConfigMapper.selectList(
            QueryWrapper<CustomerDeptConfig?>().eq("customer_id", customerId).eq(
                "dept_id",
                getContext().subCompanyId
            )
        )
        if (selectList == null || selectList.isEmpty()) {
            return null
        }
        val config = selectList[0]
        if (config.secondChargeUserId == null) {
            return null
        }
        return iCompanyUserService.getUser(config.secondChargeUserId!!)
    }

    override fun getCustomerNetConsultant(customerId: Long): CompanyUser? {
        TODO("Not yet implemented")
    }

    override fun createAccessPlan(plan: SickCustomerAccessLogPlan): ResponseBody {
        if (plan.details == null || plan.details.isEmpty()) {
            return returnError(ErrorCode.DATA_SAVE_FAILED, "请输入随访内容")
        }
        sickCustomerAccessLogPlanMapper.insert(plan)
        var orderNum = 1
        for (detail in plan.details) {
            detail.createUserId = plan.createUserId
            detail.orderNum = orderNum
            detail.planId = plan.id
            sickCustomerAccessLogPlanDetailMapper.insert(detail)
            orderNum++
        }
        return returnSuccess()
    }

}
